 package com.brc.util;
 
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.springframework.context.ResourceLoaderAware;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 import org.springframework.core.io.support.ResourcePatternResolver;
 import org.springframework.core.io.support.ResourcePatternUtils;
 import org.springframework.core.type.ClassMetadata;
 import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
 import org.springframework.core.type.classreading.MetadataReader;
 import org.springframework.core.type.classreading.MetadataReaderFactory;
 import org.springframework.core.type.filter.TypeFilter;
 import org.springframework.util.ClassUtils;
 import org.springframework.util.SystemPropertyUtils;
 
 public class ClassScaner
   implements ResourceLoaderAware
 {
   private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
 
   private final List<TypeFilter> includeFilters = new LinkedList();
 
   private final List<TypeFilter> excludeFilters = new LinkedList();
 
   private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
 
   public void setResourceLoader(ResourceLoader resourceLoader)
   {
     this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
 
     this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
   }
 
   public final ResourceLoader getResourceLoader()
   {
     return this.resourcePatternResolver;
   }
 
   public void addIncludeFilter(TypeFilter includeFilter) {
     this.includeFilters.add(includeFilter);
   }
 
   public void addExcludeFilter(TypeFilter excludeFilter) {
     this.excludeFilters.add(excludeFilter);
   }
 
   public void resetFilters(boolean useDefaultFilters) {
     this.includeFilters.clear();
     this.excludeFilters.clear();
   }
 
   public static Set<Class> scan(String basePackage, Class<?>[] classes) {
     ClassScaner classScaner = new ClassScaner();
     for (Class anno : classes)
       classScaner.addIncludeFilter(new ClassTypeFilter(anno));
     return classScaner.doScan(basePackage);
   }
 
   public static Set<Class> scan(String[] basePackages, Class<?>[] classes) {
     ClassScaner classScaner = new ClassScaner();
     for (Class anno : classes)
       classScaner.addIncludeFilter(new ClassTypeFilter(anno));
     Set classSet = new HashSet();
     for (String s : basePackages)
       classSet.addAll(classScaner.doScan(s));
     return classSet;
   }
 
   public Set<Class> doScan(String basePackage) {
     Set classes = new HashSet();
     try {
       String packageSearchPath = "classpath*:" + ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)) + "*.class";
 
       Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
 
       for (int i = 0; i < resources.length; i++) {
         Resource resource = resources[i];
         if (resource.isReadable()) {
           MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
 
           if (((this.includeFilters.size() == 0) && (this.excludeFilters.size() == 0)) || (matches(metadataReader)))
             try
             {
               classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
             }
             catch (ClassNotFoundException e) {
               e.printStackTrace();
             }
         }
       }
     }
     catch (IOException ex)
     {
       throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
     }
 
     return classes;
   }
 
   protected boolean matches(MetadataReader metadataReader) throws IOException {
     for (TypeFilter tf : this.excludeFilters) {
       if (tf.match(metadataReader, this.metadataReaderFactory)) {
         return false;
       }
     }
     for (TypeFilter tf : this.includeFilters) {
       if (tf.match(metadataReader, this.metadataReaderFactory)) {
         return true;
       }
     }
     return false;
   }
 
   public static void main(String[] ras) throws Exception {
     try {
       Set<Class> s = scan("org.springframework.core.type.filter", new Class[0]);
 
       for (Class c : s)
         System.out.println(c.getName());
     }
     catch (Exception e) {
       e.printStackTrace();
     }
   }
 }

